home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / game / shoot / ADescentSrc.lha / descent / main / morph.c < prev    next >
C/C++ Source or Header  |  1998-03-22  |  14KB  |  586 lines

  1. /*
  2. THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  3. SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
  4. END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  5. ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  6. IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  7. SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  8. FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  9. CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
  10. AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
  11. COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
  12. */
  13. /*
  14.  * $Source: /usr/CVS/descent/main/morph.c,v $
  15.  * $Revision: 1.3 $
  16.  * $Author: hfrieden $
  17.  * $Date: 1998/03/22 17:10:47 $
  18.  * 
  19.  * Morphing code
  20.  * 
  21.  * $Log: morph.c,v $
  22.  * Revision 1.3  1998/03/22 17:10:47  hfrieden
  23.  * Removed compilation error
  24.  *
  25.  * Revision 1.2  1998/03/22 15:25:56  tfrieden
  26.  * removed lots of warning messages
  27.  *
  28.  * Revision 1.1.1.1  1998/03/03 15:12:26  nobody
  29.  * reimport after crash from backup
  30.  *
  31.  * Revision 1.1.1.1  1998/02/13  20:20:59  hfrieden
  32.  * Initial Import
  33.  *
  34.  * Revision 2.1  1995/02/27  18:26:33  john
  35.  * Fixed bug that was caused by externing Polygon_models, and I had
  36.  * changed the type of it in polyobj.c, thus causing page faults.
  37.  * 
  38.  * Revision 2.0  1995/02/27  11:27:44  john
  39.  * New version 2.0, which has no anonymous unions, builds with
  40.  * Watcom 10.0, and doesn't require parsing BITMAPS.TBL.
  41.  * 
  42.  * Revision 1.35  1995/02/22  14:45:37  allender
  43.  * remove anonymous unions from object structure
  44.  * 
  45.  * Revision 1.34  1995/01/14  19:16:52  john
  46.  * First version of new bitmap paging code.
  47.  * 
  48.  * Revision 1.33  1995/01/03  20:38:36  john
  49.  * Externed MAX_MORPH_OBJECTS
  50.  * 
  51.  * Revision 1.32  1994/11/17  15:34:04  matt
  52.  * Attempt #4 to fix morph bug
  53.  * 
  54.  * Revision 1.31  1994/11/15  10:57:14  matt
  55.  * Tried again to fix morph
  56.  * 
  57.  * Revision 1.30  1994/11/14  14:06:45  matt
  58.  * Fixed stupid bug
  59.  * 
  60.  * Revision 1.29  1994/11/14  11:55:13  matt
  61.  * Added divide overflow check
  62.  * 
  63.  * Revision 1.28  1994/09/26  17:28:14  matt
  64.  * Made new multiple-object morph code work with the demo system
  65.  * 
  66.  * Revision 1.27  1994/09/26  15:39:56  matt
  67.  * Allow multiple simultaneous morphing objects
  68.  * 
  69.  * Revision 1.26  1994/09/11  22:44:59  mike
  70.  * quick on vecmat function.
  71.  * 
  72.  * Revision 1.25  1994/08/26  15:36:00  matt
  73.  * Made eclips usable on more than one object at a time
  74.  * 
  75.  * Revision 1.24  1994/07/25  00:02:46  matt
  76.  * Various changes to accomodate new 3d, which no longer takes point numbers
  77.  * as parms, and now only takes pointers to points.
  78.  * 
  79.  * Revision 1.23  1994/07/12  12:39:58  matt
  80.  * Revamped physics system
  81.  * 
  82.  * Revision 1.22  1994/06/28  11:54:51  john
  83.  * Made newdemo system record/play directly to/from disk, so
  84.  * we don't need the 4 MB buffer anymore.
  85.  * 
  86.  * Revision 1.21  1994/06/27  15:53:01  john
  87.  * #define'd out the newdemo stuff
  88.  * 
  89.  * 
  90.  * Revision 1.20  1994/06/16  14:30:19  matt
  91.  * Moved morph record data call to reder routine
  92.  * 
  93.  * Revision 1.19  1994/06/16  13:57:23  matt
  94.  * Added support for morphing objects in demos
  95.  * 
  96.  * Revision 1.18  1994/06/16  12:24:23  matt
  97.  * Made robot lighting not mess with Lighting_on so robots now night
  98.  * according to this variable.
  99.  * 
  100.  * Revision 1.17  1994/06/14  16:55:01  matt
  101.  * Got rid of physics_object speed field
  102.  * 
  103.  * Revision 1.16  1994/06/08  21:16:29  matt
  104.  * Made objects spin while morphing
  105.  * 
  106.  * Revision 1.15  1994/06/08  18:21:53  matt
  107.  * Made morphing objects light correctly
  108.  * 
  109.  * Revision 1.14  1994/06/07  16:50:49  matt
  110.  * Made object lighting work correctly; changed name of Ambient_light to
  111.  * Dynamic_light; cleaned up polygobj object rendering a little.
  112.  * 
  113.  * Revision 1.13  1994/06/01  16:33:59  yuan
  114.  * Fixed bug.
  115.  * 
  116.  * 
  117.  * Revision 1.12  1994/06/01  16:29:08  matt
  118.  * If morph_frame called on object this isn't the morph object, kill it.
  119.  * 
  120.  * Revision 1.11  1994/06/01  12:46:34  matt
  121.  * Added needed include
  122.  * 
  123.  * Revision 1.10  1994/05/31  22:12:41  matt
  124.  * Set lighting for morph objects
  125.  * Don't let another object start morph while one is morphing, unless
  126.  * that one dies.
  127.  * 
  128.  * Revision 1.9  1994/05/31  18:49:53  john
  129.  * Took out debugging printf's that Matt left in.
  130.  * 
  131.  * Revision 1.8  1994/05/30  22:50:22  matt
  132.  * Added morph effect for robots
  133.  * 
  134.  * 
  135.  * 
  136.  */
  137.  
  138.  
  139. #pragma off (unreferenced)
  140. static char rcsid[] = "$Id: morph.c,v 1.3 1998/03/22 17:10:47 hfrieden Exp $";
  141. #pragma on (unreferenced)
  142.  
  143. #include <stdio.h>
  144. #include <stdlib.h>
  145. #include <string.h>
  146. #include <bsd/bsd.h>
  147.  
  148. #include "texmap.h"
  149. #include "error.h"
  150.  
  151. #include "inferno.h"
  152. #include "morph.h"
  153. #include "polyobj.h"
  154. #include "game.h"
  155. #include "lighting.h"
  156. #include "newdemo.h"
  157. #include "piggy.h"
  158.  
  159. #include "mono.h"
  160. #include "bm.h"
  161.  
  162. morph_data morph_objects[MAX_MORPH_OBJECTS];
  163.  
  164. //returns ptr to data for this object, or NULL if none
  165. morph_data *find_morph_data(object *obj)
  166. {
  167.     int i;
  168.  
  169.     #ifdef NEWDEMO
  170.     if (Newdemo_state == ND_STATE_PLAYBACK) {
  171.         morph_objects[0].obj = obj;
  172.         return &morph_objects[0];
  173.     }
  174.     #endif
  175.  
  176.     for (i=0;i<MAX_MORPH_OBJECTS;i++)
  177.         if (morph_objects[i].obj == obj)
  178.             return &morph_objects[i];
  179.  
  180.     return NULL;
  181. }
  182.  
  183.  
  184. //takes pm, fills in min & max
  185. find_min_max(polymodel *pm,int submodel_num,vms_vector *minv,vms_vector *maxv)
  186. {
  187.     ushort nverts;
  188.     vms_vector *vp;
  189.     ushort *data,type;
  190.  
  191.     data = (ushort *) &pm->model_data[pm->submodel_ptrs[submodel_num]];
  192.  
  193.     type = *data++;
  194.  
  195.     Assert(type == 7 || type == 1);
  196.  
  197.     nverts = *data++;
  198.  
  199.     if (type==7)
  200.         data+=2;        //skip start & pad
  201.  
  202.     vp = (vms_vector *) data;
  203.  
  204.     *minv = *maxv = *vp++; nverts--;
  205.  
  206.     while (nverts--) {
  207.         if (vp->x > maxv->x) maxv->x = vp->x;
  208.         if (vp->y > maxv->y) maxv->y = vp->y;
  209.         if (vp->z > maxv->z) maxv->z = vp->z;
  210.  
  211.         if (vp->x < minv->x) minv->x = vp->x;
  212.         if (vp->y < minv->y) minv->y = vp->y;
  213.         if (vp->z < minv->z) minv->z = vp->z;
  214.  
  215.         vp++;
  216.     }
  217.  
  218. }
  219.  
  220. #define MORPH_RATE (f1_0*3)
  221.  
  222. fix morph_rate = MORPH_RATE;
  223.  
  224. init_points(polymodel *pm,vms_vector *box_size,int submodel_num,morph_data *md)
  225. {
  226.     ushort nverts;
  227.     vms_vector *vp;
  228.     ushort *data,type;
  229.     int i;
  230.  
  231.     //printf("initing %d ",submodel_num);
  232.  
  233.     data = (ushort *) &pm->model_data[pm->submodel_ptrs[submodel_num]];
  234.  
  235.     type = *data++;
  236.  
  237.     Assert(type == 7 || type == 1);
  238.  
  239.     nverts = *data++;
  240.  
  241.     md->n_morphing_points[submodel_num] = 0;
  242.  
  243.     if (type==7) {
  244.         i = *data++;        //get start point number
  245.         data++;             //skip pad
  246.     }
  247.     else
  248.         i = 0;              //start at zero
  249.  
  250.     Assert(i+nverts < MAX_VECS);
  251.  
  252.     md->submodel_startpoints[submodel_num] = i;
  253.  
  254.     vp = (vms_vector *) data;
  255.  
  256.     while (nverts--) {
  257.         fix k,dist;
  258.  
  259.         if (box_size) {
  260.             fix t;
  261.  
  262.             k = 0x7fffffff;
  263.  
  264.             if (vp->x && f2i(box_size->x)<abs(vp->x)/2 && (t = fixdiv(box_size->x,abs(vp->x))) < k) k=t;
  265.             if (vp->y && f2i(box_size->y)<abs(vp->y)/2 && (t = fixdiv(box_size->y,abs(vp->y))) < k) k=t;
  266.             if (vp->z && f2i(box_size->z)<abs(vp->z)/2 && (t = fixdiv(box_size->z,abs(vp->z))) < k) k=t;
  267.  
  268.             if (k==0x7fffffff) k=0;
  269.  
  270.         }
  271.         else
  272.             k=0;
  273.  
  274.         vm_vec_copy_scale(&md->morph_vecs[i],vp,k);
  275.  
  276.         dist = vm_vec_normalized_dir_quick(&md->morph_deltas[i],vp,&md->morph_vecs[i]);
  277.  
  278.         md->morph_times[i] = fixdiv(dist,morph_rate);
  279.  
  280.         if (md->morph_times[i] != 0)
  281.             md->n_morphing_points[submodel_num]++;
  282.  
  283.         vm_vec_scale(&md->morph_deltas[i],morph_rate);
  284.  
  285.         vp++; i++;
  286.  
  287.     }
  288.  
  289.     //printf("npoints = %d\n",n_morphing_points[submodel_num]);
  290.  
  291. }
  292.  
  293. update_points(polymodel *pm,int submodel_num,morph_data *md)
  294. {
  295.     ushort nverts;
  296.     vms_vector *vp;
  297.     ushort *data,type;
  298.     int i;
  299.  
  300.     //printf("updating %d ",submodel_num);
  301.  
  302.     data = (ushort *) &pm->model_data[pm->submodel_ptrs[submodel_num]];
  303.  
  304.     type = *data++;
  305.  
  306.     Assert(type == 7 || type == 1);
  307.  
  308.     nverts = *data++;
  309.  
  310.     if (type==7) {
  311.         i = *data++;        //get start point number
  312.         data++;             //skip pad
  313.     }
  314.     else
  315.         i = 0;              //start at zero
  316.  
  317.     vp = (vms_vector *) data;
  318.  
  319.     while (nverts--) {
  320.  
  321.         if (md->morph_times[i])     //not done yet
  322.  
  323.             if ((md->morph_times[i] -= FrameTime) <= 0) {
  324.                 md->morph_vecs[i] = *vp;
  325.                 md->morph_times[i] = 0;
  326.                 md->n_morphing_points[submodel_num]--;
  327.             }
  328.             else
  329.                 vm_vec_scale_add2(&md->morph_vecs[i],&md->morph_deltas[i],FrameTime);
  330.  
  331.         vp++; i++;
  332.     }
  333.  
  334.     //printf("npoints = %d\n",n_morphing_points[submodel_num]);
  335. }
  336.  
  337.  
  338. //process the morphing object for one frame
  339. void do_morph_frame(object *obj)
  340. {
  341.     int i;
  342.     polymodel *pm;
  343.     morph_data *md;
  344.  
  345.     md = find_morph_data(obj);
  346.  
  347.     if (md == NULL) {                   //maybe loaded half-morphed from disk
  348.         obj->flags |= OF_SHOULD_BE_DEAD;        //..so kill it
  349.         return;
  350.     }
  351.  
  352.     pm = &Polygon_models[md->obj->rtype.pobj_info.model_num];
  353.  
  354.     //printf("morph_frame active = ");
  355.     //for (i=0;i<pm->n_models;i++)
  356.     //  printf("%d ",submodel_active[i]);
  357.     //printf("\n");
  358.  
  359.  
  360.     for (i=0;i<pm->n_models;i++)
  361.         if (md->submodel_active[i]==1) {
  362.  
  363.             update_points(pm,i,md);
  364.  
  365.             if (md->n_morphing_points[i] == 0) {        //maybe start submodel
  366.                 int t;
  367.  
  368.                 md->submodel_active[i] = 2;     //not animating, just visible
  369.  
  370.                 md->n_submodels_active--;       //this one done animating
  371.  
  372.                 for (t=0;t<pm->n_models;t++)
  373.                     if (pm->submodel_parents[t] == i) {     //start this one
  374.  
  375.                         init_points(pm,NULL,t,md);
  376.                         md->n_submodels_active++;
  377.                         md->submodel_active[t] = 1;
  378.  
  379.                     }
  380.             }
  381.  
  382.         }
  383.  
  384.     if (!md->n_submodels_active) {          //done morphing!
  385.  
  386.         md->obj->control_type = md->morph_save_control_type;
  387.         md->obj->movement_type = md->morph_save_movement_type;
  388.  
  389.         md->obj->render_type = RT_POLYOBJ;
  390.  
  391.         md->obj->mtype.phys_info = md->morph_save_phys_info;
  392.  
  393.         md->obj = NULL;
  394.     }
  395.  
  396. }
  397.  
  398. vms_vector morph_rotvel = {0x4000,0x2000,0x1000};
  399.  
  400. void init_morphs(void)
  401. {
  402.     int i;
  403.  
  404.     for (i=0;i<MAX_MORPH_OBJECTS;i++)
  405.         morph_objects[i].obj = NULL;
  406. }
  407.  
  408.  
  409. //make the object morph
  410. void morph_start(object *obj)
  411. {
  412.     polymodel *pm;
  413.     vms_vector pmmin,pmmax;
  414.     vms_vector box_size;
  415.     int i;
  416.     morph_data *md;
  417.  
  418.     for (i=0;i<MAX_MORPH_OBJECTS;i++)
  419.         if (morph_objects[i].obj == NULL || morph_objects[i].obj->type==OBJ_NONE  || morph_objects[i].obj->signature!=morph_objects[i].Morph_sig)
  420.             break;
  421.  
  422.     if (i==MAX_MORPH_OBJECTS)       //no free slots
  423.         return;
  424.  
  425.     md = &morph_objects[i];
  426.  
  427.     Assert(obj->render_type == RT_POLYOBJ);
  428.  
  429.     md->obj = obj;
  430.     md->Morph_sig = obj->signature;
  431.  
  432.     md->morph_save_control_type = obj->control_type;
  433.     md->morph_save_movement_type = obj->movement_type;
  434.     md->morph_save_phys_info = obj->mtype.phys_info;
  435.  
  436.     Assert(obj->control_type == CT_AI);     //morph objects are also AI objects
  437.  
  438.     obj->control_type = CT_MORPH;
  439.     obj->render_type = RT_MORPH;
  440.     obj->movement_type = MT_PHYSICS;        //RT_NONE;
  441.  
  442.     obj->mtype.phys_info.rotvel = morph_rotvel;
  443.  
  444.     pm = &Polygon_models[obj->rtype.pobj_info.model_num];
  445.  
  446.     find_min_max(pm,0,&pmmin,&pmmax);
  447.  
  448.     box_size.x = max(-pmmin.x,pmmax.x) / 2;
  449.     box_size.y = max(-pmmin.y,pmmax.y) / 2;
  450.     box_size.z = max(-pmmin.z,pmmax.z) / 2;
  451.  
  452.     for (i=0;i<MAX_VECS;i++)        //clear all points
  453.         md->morph_times[i] = 0;
  454.  
  455.     for (i=1;i<MAX_SUBMODELS;i++)       //clear all parts
  456.         md->submodel_active[i] = 0;
  457.  
  458.     md->submodel_active[0] = 1;     //1 means visible & animating
  459.  
  460.     md->n_submodels_active = 1;
  461.  
  462.     //now, project points onto surface of box
  463.  
  464.     init_points(pm,&box_size,0,md);
  465.  
  466. }
  467.  
  468. draw_model(polymodel *pm,int submodel_num,vms_angvec *anim_angles,fix light,morph_data *md)
  469. {
  470.     int i,mn;
  471.     int facing;
  472.     int sort_list[MAX_SUBMODELS],sort_n;
  473.  
  474.  
  475.     //first, sort the submodels
  476.  
  477.     sort_list[0] = submodel_num;
  478.     sort_n = 1;
  479.  
  480.     for (i=0;i<pm->n_models;i++)
  481.  
  482.         if (md->submodel_active[i] && pm->submodel_parents[i]==submodel_num) {
  483.  
  484.             facing = g3_check_normal_facing(&pm->submodel_pnts[i],&pm->submodel_norms[i]);
  485.  
  486.             if (!facing)
  487.  
  488.                 sort_list[sort_n++] = i;
  489.  
  490.             else {      //put at start
  491.                 int t;
  492.  
  493.                 for (t=sort_n;t>0;t--)
  494.                     sort_list[t] = sort_list[t-1];
  495.  
  496.                 sort_list[0] = i;
  497.  
  498.                 sort_n++;
  499.  
  500.  
  501.             }
  502.  
  503.         }
  504.     
  505.  
  506.     //now draw everything
  507.  
  508.     for (i=0;i<sort_n;i++) {
  509.  
  510.         mn = sort_list[i];
  511.  
  512.         if (mn == submodel_num) {
  513.             int i;
  514.  
  515.             for (i=0;i<pm->n_textures;i++)      {
  516.                 texture_list_index[i] = ObjBitmaps[ObjBitmapPtrs[pm->first_texture+i]];
  517.                 texture_list[i] = &GameBitmaps[ObjBitmaps[ObjBitmapPtrs[pm->first_texture+i]].index];
  518.             }
  519.  
  520. #ifdef PIGGY_USE_PAGING         
  521.             // Make sure the textures for this object are paged in...
  522.             piggy_page_flushed = 0;
  523.             for (i=0;i<pm->n_textures;i++)  
  524.                 PIGGY_PAGE_IN( texture_list_index[i] );
  525.             // Hmmm... cache got flushed in the middle of paging all these in,
  526.             // so we need to reread them all in.
  527.             if (piggy_page_flushed) {
  528.                 piggy_page_flushed = 0;
  529.                 for (i=0;i<pm->n_textures;i++)  
  530.                     PIGGY_PAGE_IN( texture_list_index[i] );
  531.             }
  532.             // Make sure that they can all fit in memory.
  533.             Assert( piggy_page_flushed == 0 );
  534. #endif
  535.  
  536.  
  537.             g3_draw_morphing_model(&pm->model_data[pm->submodel_ptrs[submodel_num]],texture_list,anim_angles,light,&md->morph_vecs[md->submodel_startpoints[submodel_num]]);
  538.  
  539.         }
  540.         else {
  541.  
  542.             vms_matrix orient;
  543.  
  544.             vm_angles_2_matrix(&orient,&anim_angles[mn]);
  545.  
  546.             g3_start_instance_matrix(&pm->submodel_offsets[mn],&orient);
  547.  
  548.             draw_model(pm,mn,anim_angles,light,md);
  549.  
  550.             g3_done_instance();
  551.  
  552.         }
  553.     }
  554.  
  555. }
  556.  
  557. void draw_morph_object(object *obj)
  558. {
  559. //  int save_light;
  560.     polymodel *po;
  561.     fix light;
  562.     morph_data *md;
  563.  
  564.     md = find_morph_data(obj);
  565.     Assert(md != NULL);
  566.  
  567.     Assert(obj->rtype.pobj_info.model_num < N_polygon_models);
  568.  
  569.     po=&Polygon_models[obj->rtype.pobj_info.model_num];
  570.  
  571.     light = compute_object_light(obj,NULL);
  572.  
  573.     g3_start_instance_matrix(&obj->pos,&obj->orient);
  574.     g3_set_interp_points(robot_points);
  575.  
  576.     draw_model(po,0,obj->rtype.pobj_info.anim_angles,light,md);
  577.  
  578.     g3_done_instance();
  579.  
  580.     #ifdef NEWDEMO
  581.     if (Newdemo_state == ND_STATE_RECORDING)
  582.         newdemo_record_morph_frame(md);
  583.     #endif
  584.  
  585. }
  586.